/*
 * Copyright 2016-2017 TVI Go Easy.
 * Created on 2017/8/4 20:50
 */
package com.gitee.mechanic.core.utils;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.apache.commons.lang3.StringUtils;

import java.lang.Character.UnicodeBlock;

/**
 * 中文拼音工具类
 *
 * @author mechanic
 */
public class PinyinUtils {

    private static final String SEPRATE = "";
    private static final HanyuPinyinOutputFormat OUTPUT_FORMAT = new HanyuPinyinOutputFormat();

    static {
        OUTPUT_FORMAT.setCaseType(HanyuPinyinCaseType.UPPERCASE);
        OUTPUT_FORMAT.setVCharType(HanyuPinyinVCharType.WITH_V);
        OUTPUT_FORMAT.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
    }

    /**
     * 返回汉字的无分隔符大写全拼
     *
     * @param str 汉字
     * @return 大写全拼
     */
    public static String getPinyin(String str) {
        return getPinyin(str, SEPRATE);
    }

    /**
     * 返回汉字的指定分隔符大写全拼
     * <strong>!!!</strong>pinyin4j加入分隔符🈶️有Bug，如输入"中文汉字"且分隔符为"|"，返回的是"ZHONG|WEN|HANZI"，
     * 因此在pinyin4j没有更新前，该方法暂不对外开放。
     *
     * @param str      str 汉字
     * @param separate 分隔符
     * @return 大写全拼
     */
    private static String getPinyin(String str, String separate) {
        String result = "";
        try {
            result = PinyinHelper.toHanYuPinyinString(str, OUTPUT_FORMAT, separate, true);
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 返回汉字的大写首字母
     *
     * @param str 汉字
     * @return 首字母
     */
    public static String getAllFirst(String str) {
        StringBuilder stringBuilder = new StringBuilder();
        char[] chars = str.toCharArray();
        for (char c : chars) {
            String[] strs = PinyinHelper.toHanyuPinyinStringArray(c);
            if (strs.length > 0) {
                stringBuilder.append(strs[0].charAt(0));
            }
        }
        return stringBuilder.toString().toUpperCase();
    }

    public static String getFirst(String str) {
        return getFirst(str, null, null);
    }

    public static String getFirst(String str, HanyuPinyinOutputFormat format) {
        return getFirst(str, format, null);
    }

    /**
     * 获取中文的拼音首字母，数字或英文直接返回第一个字符，符号则返回#
     *
     * @param str      字符串
     * @param format   格式
     * @param separate 分隔符
     * @return 字符串
     */
    private static String getFirst(
      String str, HanyuPinyinOutputFormat format,
      String separate) {

        if (StringUtils.isBlank(str)) {
            return "";
        }

        format = (format == null) ? OUTPUT_FORMAT : format;
        separate = StringUtils.isBlank(separate) ? SEPRATE : separate;

        String result = "";
        char c = str.charAt(0);
        String s = String.valueOf(str.charAt(0));

        //判断是否英文字母
        if (StringUtils.isAllLowerCase(s.toLowerCase())) {
            result = s;
        }
        //判断是否中文
        else if (!isChinese(c)) {
            result = "#";
        } else {

            try {
                result = PinyinHelper.toHanYuPinyinString(s, format, separate, true);
            } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {
                badHanyuPinyinOutputFormatCombination.printStackTrace();
            }
            result = String.valueOf(result.charAt(0));
        }
        if (format.getCaseType() == HanyuPinyinCaseType.UPPERCASE) {
            return result.toUpperCase();
        } else {
            return result.toLowerCase();
        }
    }

    public static boolean isChinese(char c) {
        UnicodeBlock ub = UnicodeBlock.of(c);
        return ub == UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
               || ub == UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
               || ub == UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
               || ub == UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C //jdk1.7
               || ub == UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D //jdk1.7
               || ub == UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
               || ub == UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT;
    }
}
